package com.dd.stack.es.service.internal.impl;

import com.dd.stack.es.pojo.es.ProductESDO;
import com.dd.stack.es.pojo.req.ProductESReq;
import com.dd.stack.es.repository.ProductRepository;
import com.dd.stack.es.service.internal.ProductService;
import lombok.RequiredArgsConstructor;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author liuxianmeng
 * @CreateTime 2024/10/30 19:49
 * @Description 类功能作用说明
 */
@Service
@RequiredArgsConstructor
public class ProductServiceImpl implements ProductService {

    private final ProductRepository productRepository;
    private final ElasticsearchOperations elasticsearchOperations;

    @Override
    public ProductESDO add(ProductESDO product) {
        return productRepository.save(product);
    }

    @Override
    public ProductESDO get(String id) {
        return productRepository.findById(id).orElse(null);
    }

    @Override
    public List<ProductESDO> getByName(String name) {
        // 创建查询条件，根据产品名称进行模糊匹配（这里使用通配符进行模糊查询，可根据实际需求调整查询方式）
        Criteria criteria = Criteria.where("name").matches(name + "*")
                .and("description").matches(".*描述.*");
        // 创建查询对象
        CriteriaQuery query = new CriteriaQuery(criteria);
        // 设置分页信息，这里假设每页显示10条记录，获取第一页数据（可根据实际需求调整分页参数）
        PageRequest pageRequest = PageRequest.of(0, 2);
        query.setPageable(pageRequest);
        // 执行查询操作
        SearchHits<ProductESDO> search = elasticsearchOperations.search(query, ProductESDO.class);
        // 将查询结果转换为List<ProductESDO>并返回
        List<ProductESDO> resultList = new ArrayList<>();
        search.forEach(hit -> resultList.add(hit.getContent()));
        return resultList;
    }

    /* 全量分页查询(考虑所有条件) */
    @Override
    public PageImpl<ProductESDO> search(ProductESReq req) {
        // 构建原生查询（添加排序）
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(req.buildBoolQuery())
                .withPageable(req.buildPageable())
                //.withSort(new FieldSortBuilder("name").order(SortOrder.ASC))  // 添加排序
                .build();

        // 执行查询
        SearchHits<ProductESDO> searchHits = elasticsearchOperations.search(searchQuery, ProductESDO.class);

        // 转换为分页结果
        List<ProductESDO> products = searchHits.stream()
                .map(SearchHit::getContent)
                .collect(Collectors.toList());

        return new PageImpl<>(products, req.buildPageable(), searchHits.getTotalHits());
    }

    /* 满足条件的所有条目总数 */
    private long searchCount(CriteriaQuery query) {
        return elasticsearchOperations.count(query, ProductESDO.class);
    }

    @Override
    public ProductESDO updateProduct(ProductESDO product) {
        return productRepository.save(product);
    }

    @Override
    public void deleteProductById(String id) {
        productRepository.deleteById(id);
    }
}
